home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_300 / 359_11 / patch5.000 / GO32 / EXPHDLR.C < prev    next >
Encoding:
C/C++ Source or Header  |  1991-09-11  |  18.2 KB  |  746 lines

  1. /* This is file EXPHDLR.C */
  2. /*
  3. ** Copyright (C) 1991 DJ Delorie, 24 Kirsten Ave, Rochester NH 03867-2954
  4. **
  5. ** This file is distributed under the terms listed in the document
  6. ** "copying.dj", available from DJ Delorie at the address above.
  7. ** A copy of "copying.dj" should accompany this file; if not, a copy
  8. ** should be available from where this file was obtained.  This file
  9. ** may not be distributed without a verbatim copy of "copying.dj".
  10. **
  11. ** This file is distributed WITHOUT ANY WARRANTY; without even the implied
  12. ** warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  13. */
  14.  
  15. /* Modified for VCPI Implement by Y.Shibata Aug 5th 1991 */
  16. /* History:66,55 */
  17.  
  18. #include <process.h>
  19. #include <stdio.h>
  20. #include <dos.h>
  21. #include <sys/stat.h>
  22. #include <time.h>
  23. #include <errno.h>
  24. #include <fcntl.h>
  25.  
  26. #include "build.h"
  27. #include "types.h"
  28. #include "gdt.h"
  29. #include "idt.h"
  30. #include "tss.h"
  31. #include "utils.h"
  32. #include "paging.h"
  33. #include "npx.h"
  34. #include "mono.h"
  35. #include "vcpi.h"
  36.  
  37. #define SEGFAULT(p) { \
  38.   printf("Segmentation violation in pointer 0x%08lx\n", (p)); \
  39.   return 1; \
  40.   }
  41.  
  42. extern word32 far *graphics_pt;
  43.  
  44. extern int was_user_int;
  45. extern word16 vcpi_installed;        /* VCPI Installed flag */
  46. static word16 master_pic = 0x08;    /* Default IRQ0 Vector */
  47. char transfer_buffer[4096];    /* must be near ptr for small model */
  48.  
  49. word32 user_dta;
  50. static struct REGPACK r;
  51. static int in_graphics_mode=0;
  52.  
  53. static word32 flmerge(word32 rf, word32 tf)
  54. {
  55.   return (rf & 0xcff) | (tf & 0xfffff300L);
  56. }
  57.  
  58. static set_controller(v)
  59. {
  60. /*  disable();  */
  61.   outportb(0x20, 0x11);
  62.   outportb(0x21, v);
  63.   outportb(0x21, 4);
  64.   outportb(0x21, 1);
  65. /*  enable();  */
  66. }
  67.  
  68. init_controllers()
  69. {
  70.   disable();
  71.   movedata(0, 0x08*4, 0, 0x78*4, 0x08*4);
  72.   if (vcpi_installed)
  73.     {
  74.     master_pic = vcpi_get_pic();
  75.     vcpi_set_pic(0x78);
  76.     }
  77.   set_controller(0x78);
  78.   enable();
  79. }
  80.  
  81. uninit_controllers()
  82. {
  83.   disable();
  84.   if (vcpi_installed)
  85.     vcpi_set_pic(master_pic);
  86.   set_controller(master_pic);
  87.   enable();
  88. }
  89.  
  90. extern int ctrl_c_flag;
  91.  
  92. exception_handler()
  93. {
  94.   int i;
  95. #if TOPLINEINFO
  96.   char buf[20];
  97.   sprintf(buf, "0x%08lx", tss_ptr->tss_eip);
  98.   for (i=0; buf[i]; i++)
  99.     poke(screen_seg, i*2+80, buf[i] | 0x0600);
  100. #endif
  101.   i = tss_ptr->tss_irqn;
  102. /*  printf("i=%#02x, a0=%02x\n", i, inportb(0xa0)); */
  103.   if ((i>=0x70) && (i<0x7f) && (i != 0x75))
  104.   {
  105.     if (i<0x78)
  106.       intr(i, &r);
  107.     else
  108.       intr(i-0x70, &r);
  109.     if (i == 0x79)
  110.     {
  111.       r.r_ax = 0x0100;
  112.       intr(0x16, &r);
  113.       if (!(r.r_flags & 0x40) && (r.r_ax == 0x2e03))
  114.       {
  115.         _AH = 0;
  116.         geninterrupt(0x16);
  117.         ctrl_c_flag = 1;
  118.       }
  119.     }
  120.     if (ctrl_c_flag)
  121.     {
  122.       ctrl_c_flag = 0;
  123.       return 1;
  124.     }
  125.     return 0;
  126.   }
  127.   switch (i)
  128.   {
  129.     case 8:
  130.       printf("double fault!\n");
  131.       exit(1);
  132.     case 0:
  133.     case 1:
  134.     case 2:
  135.     case 3:
  136.     case 4:
  137.     case 5:
  138.     case 6:
  139.     case 9:
  140.     case 10:
  141.     case 11:
  142.     case 12:
  143.     case 13:
  144.     case 15:
  145.       return 1;
  146.     case 0x75:
  147.       return 1;
  148.     case 7:
  149.       printf("Fatal!  Application attempted to use not-present 80387!\n");
  150.       printf("Floating point opcode at virtual address 0x%08lx\n", tss_ptr->tss_eip);
  151.       return 1;
  152.     case 14:
  153.       return page_in();
  154.  
  155.     case 0x10:
  156.       return i_10();
  157.     case 0x11:
  158.     case 0x12:
  159.     case 0x14:
  160.     case 0x16:
  161.     case 0x17:
  162.     case 0x1a:
  163.       return generic_handler();
  164.     case 0x21:
  165.       return i_21();
  166.     case 0x33:
  167.       return i_33();
  168.     default:
  169.       return 1;
  170.   }
  171. }
  172.  
  173. #if DEBUGGER
  174. static char flset[] = "VMRF  NT    OFDNIETFMIZR  AC  PE  CY";
  175. static char floff[] = "              UPID  PLNZ      PO  NC";
  176. static char fluse[] = {1,1,0,1,0,0,1,1,1,1,1,1,0,1,0,1,0,1};
  177.  
  178. tssprint(TSS *t)
  179. {
  180.   int i;
  181.   printf("eax=%08lx  ebx=%08lx  ecx=%08lx  edx=%08lx\n",
  182.     t->tss_eax, t->tss_ebx, t->tss_ecx, t->tss_edx);
  183.   printf("esi=%08lx  edi=%08lx  ebp=%08lx ",
  184.     t->tss_esi, t->tss_edi, t->tss_ebp);
  185.   for (i=0; i<18; i++)
  186.     if (fluse[i])
  187.       if (t->tss_eflags & (1<<(17-i)))
  188.         printf(" %2.2s", flset+i*2);
  189.       else
  190.         printf(" %2.2s", floff+i*2);
  191.   printf("\nds=%04x es=%04x fs=%04x gs=%04x ss:esp=%04x:%08lx cs=%04x\n",
  192.     t->tss_ds, t->tss_es, t->tss_fs, t->tss_gs, t->tss_ss, t->tss_esp, t->tss_cs);
  193. }
  194. #endif /* DEBUGGER */
  195.  
  196. int retrieve_string(word32 v, char *transfer_buffer, char tchar)
  197. {
  198.   int i;
  199.   char c;
  200.   for (i=0; i<4096; i++)
  201.   {
  202.     c = peek8(v);
  203.     v++;
  204.     transfer_buffer[i] = c;
  205.     if (c == tchar)
  206.       break;
  207.   }
  208.   return i+1; /* number of characters placed in buffer */
  209. }
  210.  
  211. static int old_text_mode = -1;
  212.  
  213. generic_handler()
  214. {
  215.   tss2reg(&r);
  216.   intr(tss_ptr->tss_irqn, &r);
  217.   reg2tss(&r);
  218.   return 0;
  219. }
  220.  
  221. i_10()
  222. {
  223.   if ((tss_ptr->tss_eax & 0xFF00) == 0xFF00)
  224.   {
  225.     graphics_mode(tss_ptr->tss_eax & 0xff);
  226.     in_graphics_mode = (peekb(0x40, 0x49) > 7);
  227.     return 0;
  228.   }
  229.   tss2reg(&r);
  230.   intr(0x10, &r);
  231.   reg2tss(&r);
  232.   tss_ptr->tss_ebp = r.r_es * 16L + r.r_bp + 0xe0000000L;
  233.   return 0;
  234. }
  235.  
  236. i_33()
  237. {
  238.   if (*((unsigned far *)0x000000CEL) == 0)
  239.     return 0;
  240.   r.r_ax = tss_ptr->tss_eax;
  241.   r.r_bx = tss_ptr->tss_ebx;
  242.   r.r_cx = tss_ptr->tss_ecx;
  243.   r.r_dx = tss_ptr->tss_edx;
  244.   intr(0x33, &r);
  245.   tss_ptr->tss_eax = r.r_ax;
  246.   tss_ptr->tss_ebx = r.r_bx;
  247.   tss_ptr->tss_ecx = r.r_cx;
  248.   tss_ptr->tss_edx = r.r_dx;
  249.   return 0;
  250. }
  251.  
  252. TSS last_tss;
  253.  
  254. i_21()
  255. {
  256.   word32 v, trans_total, countleft;
  257.   int i, c, ah, tchar, trans_count;
  258.   char *cp;
  259.   memcpy(&last_tss, tss_ptr, sizeof(TSS));
  260.   tss2reg(&r);
  261.   ah = (tss_ptr->tss_eax >> 8) & 0xff;
  262. #if 0
  263.   printf("int 21h ax=0x%04x bx=0x%04x cx=0x%04x dx=0x%04x\n",
  264.     (int)(tss_ptr->tss_eax),
  265.     (int)(tss_ptr->tss_ebx),
  266.     (int)(tss_ptr->tss_ecx),
  267.     (int)(tss_ptr->tss_edx)
  268.     );
  269. #endif
  270.   switch (ah)
  271.   {
  272.     case 1:
  273.     case 2:
  274.     case 3:
  275.     case 4:
  276.     case 5:
  277.     case 6:
  278.     case 7:
  279.     case 8:
  280.     case 0x0b:
  281.     case 0x0e:
  282.     case 0x19:
  283.     case 0x2a:
  284.     case 0x2b:
  285.     case 0x2c:
  286.     case 0x2d:
  287.     case 0x33:
  288.     case 0x42:
  289.     case 0x45:
  290.     case 0x46:
  291.     case 0x57:
  292.     case 0x68:
  293.       intr(0x21, &r);
  294.       reg2tss(&r);
  295.       return 0;
  296.     case 0x3e:
  297. #if DEBUGGER
  298.       if (r.r_bx <= 2)
  299.         return 0;
  300. #endif
  301.       if (r.r_bx == 1)
  302.         redir_1_mono = redir_1_2 = 0;
  303.       if (r.r_bx == 2)
  304.         redir_2_mono = redir_2_1 = 0;
  305.       intr(0x21, &r);
  306.       reg2tss(&r);
  307.       return 0;
  308.     case 9:
  309.     case 0x39:
  310.     case 0x3a:
  311.     case 0x3b:
  312.     case 0x41:
  313.     case 0x43:
  314.       if (ah == 9)
  315.         tchar = '$';
  316.       else
  317.         tchar = 0;
  318.       v = tss_ptr->tss_edx + ARENA;
  319.       if (!page_is_valid(v))
  320.       {
  321.         printf("Segmentation violation in pointer 0x%08lx\n", tss_ptr->tss_edx);
  322.         return 1;
  323.       }
  324.       retrieve_string(v, transfer_buffer, tchar);
  325.       r.r_dx = FP_OFF(transfer_buffer);
  326.       r.r_ds = _DS;
  327.       intr(0x21, &r);
  328.       reg2tss(&r);
  329.       return 0;
  330.     case 0x3c:
  331.       v = tss_ptr->tss_edx + ARENA;
  332.       if (!page_is_valid(v))
  333.       {
  334.         printf("Segmentation violation in pointer 0x%08lx\n", tss_ptr->tss_edx);
  335.         return 1;
  336.       }
  337.       retrieve_string(v, transfer_buffer, 0);
  338.       i = _creat(transfer_buffer, (int)(tss_ptr->tss_ecx));
  339.       if (i < 0)
  340.       {
  341.         tss_ptr->tss_eax = errno;
  342.         tss_ptr->tss_eflags |= 1;
  343.       }
  344.       else
  345.       {
  346.         tss_ptr->tss_eax = i;
  347.         tss_ptr->tss_eflags &= ~1;
  348.       }
  349.       return 0;
  350.     case 0x3d:
  351.       v = tss_ptr->tss_edx + ARENA;
  352.       if (!page_is_valid(v))
  353.       {
  354.         printf("Segmentation violation in pointer 0x%08lx\n", tss_ptr->tss_edx);
  355.         return 1;
  356.       }
  357.       retrieve_string(v, transfer_buffer, 0);
  358.       i = tss_ptr->tss_eax & 0xf0;
  359.       if (tss_ptr->tss_eax & O_WRONLY) i &= 1;
  360.       if (tss_ptr->tss_eax & O_RDWR) i &= 2;
  361.       i = _open(transfer_buffer, i);
  362.       if (i < 0)
  363.       {
  364.         tss_ptr->tss_eax = errno;
  365.         tss_ptr->tss_eflags |= 1;
  366.       }
  367.       else
  368.       {
  369.         tss_ptr->tss_eax = i;
  370.         tss_ptr->tss_eflags &= ~1;
  371.       }
  372.       return 0;
  373.     case 0x1a:
  374.       user_dta = tss_ptr->tss_edx;
  375.       setdta((char far *)transfer_buffer);
  376.       return 0;
  377.     case 0x2f:
  378.       tss_ptr->tss_ebx = user_dta;
  379.       return 0;
  380.     case 0x30:
  381.       intr(0x21, &r);
  382.       reg2tss(&r);
  383.       return 0;
  384.     case 0x56:
  385.       v = tss_ptr->tss_edx + ARENA;
  386.       if (!page_is_valid(v))
  387.       {
  388.         printf("Segmentation violation in pointer 0x%08lx\n", tss_ptr->tss_edx);
  389.         return 1;
  390.       }
  391.       i = retrieve_string(v, transfer_buffer, 0);
  392.       r.r_dx = FP_OFF(transfer_buffer);
  393.       r.r_ds = _DS;
  394.       v = tss_ptr->tss_edi + ARENA;
  395.       retrieve_string(v, transfer_buffer+i, 0);
  396.       r.r_di = FP_OFF(transfer_buffer)+i;
  397.       r.r_es = _DS;
  398.       intr(0x21, &r);
  399.       tss_ptr->tss_eax = r.r_ax;
  400.       tss_ptr->tss_eflags = flmerge(r.r_flags, tss_ptr->tss_eflags);
  401.       return 0;
  402.     case 0x3f:
  403.       trans_total = 0;
  404.       countleft = tss_ptr->tss_ecx;
  405.       v = tss_ptr->tss_edx;
  406.       if (!page_is_valid(v+ARENA))
  407.       {
  408.         printf("Segmentation violation in pointer 0x%08lx\n", tss_ptr->tss_edx);
  409.         return 1;
  410.       }
  411.       while (countleft > 0)
  412.       {
  413.         trans_count = (countleft <= 4096) ? countleft : 4096;
  414.         i = read(r.r_bx, transfer_buffer, trans_count);
  415.         if (i < 0)
  416.         {
  417.           tss_ptr->tss_eflags |= 1; /* carry */
  418.           tss_ptr->tss_eax = _doserrno;
  419.           return 0;
  420.         }
  421.         memput(v+ARENA, transfer_buffer, i);
  422.         trans_total += i;
  423.         v += i;
  424.         countleft -= i;
  425.         if (isatty(r.r_bx) && (i<trans_count))
  426.           break; /* they're line buffered */
  427.         if (i == 0)
  428.           break;
  429.       }
  430.       tss_ptr->tss_eax = trans_total;
  431.       tss_ptr->tss_eflags &= ~1;
  432.       return 0;
  433.     case 0x40:
  434.       trans_total = 0;
  435.       countleft = tss_ptr->tss_ecx;
  436.       if (countleft == 0)
  437.       {
  438.         r.r_ax = 0x4000;
  439.         r.r_cx = 0;
  440.         intr(0x21,&r);
  441.         tss_ptr->tss_eax = 0;
  442.         tss_ptr->tss_eflags &= ~1;
  443.         return 0;
  444.       }
  445.       v = tss_ptr->tss_edx;
  446.       if (!page_is_valid(v+ARENA))
  447.         SEGFAULT(v);
  448.       r.r_dx = (int)transfer_buffer;
  449.       while (countleft > 0)
  450.       {
  451.         trans_count = (countleft <= 4096) ? countleft : 4096;
  452.         memget(v+ARENA, transfer_buffer, trans_count);
  453.         if ((r.r_bx == 1) && redir_1_mono)
  454.           i = mono_write(transfer_buffer, trans_count);
  455.         else if ((r.r_bx == 2) && redir_2_mono)
  456.           i = mono_write(transfer_buffer, trans_count);
  457.         else
  458.         {
  459.           int fd = r.r_bx;
  460.           if ((r.r_bx == 2) && redir_2_1)
  461.             fd = 1;
  462.           else if ((r.r_bx == 1) && redir_1_2)
  463.             fd = 2;
  464.           i = write(fd, transfer_buffer, trans_count);
  465.           if (in_graphics_mode && (fd < 3))
  466.           {
  467.             word32 far *p = graphics_pt;
  468.             for (c = 0; c < 256; c++)
  469.               *p++ &= ~PT_P;
  470.           }
  471.         }
  472.         if (i<0) /* carry */
  473.         {
  474.           tss_ptr->tss_eflags |= 1; /* carry */
  475.           tss_ptr->tss_eax = _doserrno;
  476.           return 0;
  477.         }
  478.         trans_total += i;
  479.         v += i;
  480.         countleft -= i;
  481.         if (i < trans_count)
  482.           break;
  483.       }
  484.       tss_ptr->tss_eax = trans_total;
  485.       tss_ptr->tss_eflags &= ~1;
  486.       return 0;
  487.     case 0x44:
  488.       return i_21_44();
  489.     case 0x4e:
  490.       if (!page_is_valid(user_dta+ARENA))
  491.         SEGFAULT(user_dta);
  492.       v = tss_ptr->tss_edx + ARENA;
  493.       if (!page_is_valid(v))
  494.         SEGFAULT(v);
  495.       retrieve_string(v, transfer_buffer+43, 0);
  496.       r.r_dx = FP_OFF(transfer_buffer+43);
  497.       r.r_ds = _DS;
  498.       intr(0x21, &r);
  499.       reg2tss(&r);
  500.       for (i=20; i>=0; i--)
  501.         transfer_buffer[i+28] = transfer_buffer[i+26];
  502.       transfer_buffer[32+13] = 0; /* asciiz termination */
  503.       memput(user_dta+ARENA, transfer_buffer, 48);
  504.       return 0;
  505.     case 0x4f:
  506.       if (!page_is_valid(user_dta+ARENA))
  507.         SEGFAULT(user_dta);
  508.       memget(user_dta+ARENA, transfer_buffer, 48);
  509.       for (i=0; i<=20; i++)
  510.         transfer_buffer[i+26] = transfer_buffer[i+28];
  511.       intr(0x21, &r);
  512.       reg2tss(&r);
  513.       for (i=20; i>=0; i--)
  514.         transfer_buffer[i+28] = transfer_buffer[i+26];
  515.       transfer_buffer[32+13] = 0; /* asciiz termination */
  516.       memput(user_dta+ARENA, transfer_buffer, 48);
  517.       return 0;
  518.     case 0x47:
  519.       getcurdir((int)(tss_ptr->tss_edx & 0xff), transfer_buffer);
  520.       for (cp=transfer_buffer; *cp; cp++)
  521.       {
  522.         if (*cp == '\\') *cp = '/';
  523.         *cp = tolower(*cp);
  524.       }
  525.       memput(tss_ptr->tss_esi+ARENA, transfer_buffer, strlen(transfer_buffer));
  526.       tss_ptr->tss_eax = (unsigned)r.r_ax;
  527.       tss_ptr->tss_eflags &= ~1;
  528.       return 0;
  529.     case 0x4a:
  530.       if (tss_ptr->tss_eax & 0xff)
  531.         tss_ptr->tss_eax = paging_sbrk(tss_ptr->tss_ebx);
  532.       else
  533.         tss_ptr->tss_eax = paging_brk(tss_ptr->tss_ebx);
  534.       return 0;
  535.     case 0x4c:
  536. #if DEBUGGER
  537.       printf("Program exited normally, return code %d (0x%x)\n",
  538.              (int)(tss_ptr->tss_eax & 0xff), (int)(tss_ptr->tss_eax & 0xff));
  539.       return 1;
  540. #else
  541.       exit(tss_ptr->tss_eax & 0xff);
  542. #endif
  543.     case 0xff:
  544.       return turbo_assist();
  545.     default:
  546.       return 1;
  547.   }
  548. }
  549.  
  550. struct time32 {
  551.   word32 secs;
  552.   word32 usecs;
  553. };
  554.  
  555. struct tz32 {
  556.   word32 offset;
  557.   word32 dst;
  558. };
  559.  
  560. struct    stat32 {
  561.     short st_dev;
  562.     short st_ino;
  563.     short st_mode;
  564.     short st_nlink;
  565.     short st_uid;
  566.     short st_gid;
  567.     short st_rdev;
  568.     short st_align_for_word32;
  569.     long  st_size;
  570.     long  st_atime;
  571.     long  st_mtime;
  572.     long  st_ctime;
  573.     long  st_blksize;
  574. };
  575.  
  576. static int dev_count=1;
  577.  
  578. turbo_assist()
  579. {
  580.   word32 p1, p2, p3, r;
  581.   struct time32 time32;
  582.   struct tz32 tz32;
  583.   struct stat32 statbuf32;
  584.   struct stat statbuf;
  585.   int i;
  586.  
  587.   char buf[128];
  588.   p1 = tss_ptr->tss_ebx;
  589.   p2 = tss_ptr->tss_ecx;
  590.   p3 = tss_ptr->tss_edx;
  591.   switch (tss_ptr->tss_eax & 0xff)
  592.   {
  593.     case 1:
  594.       retrieve_string(p1+ARENA, buf, 0);
  595.       r = creat(buf, S_IREAD | S_IWRITE);
  596.       break;
  597.     case 2:
  598.       retrieve_string(p1+ARENA, buf, 0);
  599.       r = open(buf, (int)p2, S_IREAD | S_IWRITE);
  600.       break;
  601.     case 3:
  602.       memset(&statbuf, 0, sizeof(statbuf));
  603.       r = fstat((int)p1, &statbuf);
  604.       statbuf32.st_dev = dev_count++;
  605.       statbuf32.st_ino = statbuf.st_ino;
  606.       statbuf32.st_mode = statbuf.st_mode;
  607.       statbuf32.st_nlink = statbuf.st_nlink;
  608.       statbuf32.st_uid = statbuf.st_uid;
  609.       statbuf32.st_gid = statbuf.st_gid;
  610.       statbuf32.st_rdev = statbuf.st_rdev;
  611.       statbuf32.st_size = statbuf.st_size;
  612.       statbuf32.st_atime = statbuf.st_atime;
  613.       statbuf32.st_mtime = statbuf.st_mtime;
  614.       statbuf32.st_ctime = statbuf.st_ctime;
  615.       statbuf32.st_blksize = 512;
  616.       memput(p2+ARENA, &statbuf32, sizeof(statbuf32));
  617.       break;
  618.     case 4:
  619.       if (p2)
  620.       {
  621.         if (!page_is_valid(p2+ARENA))
  622.           SEGFAULT(p2);
  623.         tz32.offset = timezone;
  624.         tz32.dst = daylight;
  625.         memput(p2+ARENA, &tz32, sizeof(tz32));
  626.       }
  627.       if (p1)
  628.       {
  629.         if (!page_is_valid(p1+ARENA))
  630.           SEGFAULT(p1);
  631.         time(&(time32.secs));
  632.         _AH = 0x2c;
  633.         geninterrupt(0x21);
  634.         time32.usecs = _DL * 10000L;
  635.         memput(p1+ARENA, &time32, sizeof(time32));
  636.       }
  637.       r = 0;
  638.       break;
  639.     case 5:
  640.       if (p2)
  641.       {
  642.         if (!page_is_valid(p2+ARENA))
  643.           SEGFAULT(p2);
  644.         memget(p2+ARENA, &tz32, sizeof(tz32));
  645.         timezone = tz32.offset;
  646.         daylight = tz32.dst;
  647.       }
  648.       if (p1)
  649.       {
  650.         if (!page_is_valid(p1+ARENA))
  651.           SEGFAULT(p1);
  652.         memget(p1+ARENA, &time32, sizeof(time32));
  653.         stime(&(time32.secs));
  654.       }
  655.       r = 0;
  656.       break;
  657.     case 6:
  658.       memset(&statbuf, 0, sizeof(statbuf));
  659.       retrieve_string(p1+ARENA, transfer_buffer, 0);
  660.       r = stat(transfer_buffer, &statbuf);
  661.       statbuf32.st_dev = dev_count++;
  662.       statbuf32.st_ino = statbuf.st_ino;
  663.       statbuf32.st_mode = statbuf.st_mode;
  664.       statbuf32.st_nlink = statbuf.st_nlink;
  665.       statbuf32.st_uid = statbuf.st_uid;
  666.       statbuf32.st_gid = statbuf.st_gid;
  667.       statbuf32.st_rdev = statbuf.st_rdev;
  668.       statbuf32.st_size = statbuf.st_size;
  669.       statbuf32.st_atime = statbuf.st_atime;
  670.       statbuf32.st_mtime = statbuf.st_mtime;
  671.       statbuf32.st_ctime = statbuf.st_ctime;
  672.       statbuf32.st_blksize = 512;
  673.       memput(p2+ARENA, &statbuf32, sizeof(statbuf32));
  674.       break;
  675.     case 7:
  676.       retrieve_string(p1+ARENA, transfer_buffer, 0);
  677.       page_out_everything();
  678.       uninit_controllers();
  679.       sscanf(transfer_buffer, "%s%n", buf, &i);
  680.       if (strpbrk(transfer_buffer, "<>|") == NULL)
  681.         r = spawnlp(P_WAIT, buf, buf, transfer_buffer+i, 0);
  682.       else
  683.         r = -1;
  684.       if (r & 0x80000000L)
  685.         r = system(transfer_buffer);
  686.       init_controllers();
  687.       page_in_everything();
  688.       break;
  689.     case 8:
  690.       r = setmode((int)p1, (int)p2);
  691.       break;
  692.     default:
  693.       return 1;
  694.   }
  695.   tss_ptr->tss_eflags &= ~1;
  696.   if (r == -1)
  697.   {
  698.     tss_ptr->tss_eflags |= 1;
  699.     tss_ptr->tss_eax = errno;
  700.     return 0;
  701.   }
  702.   tss_ptr->tss_eax = r;
  703.   return 0;
  704. }
  705.  
  706. i_21_44()
  707. {
  708.   switch (tss_ptr->tss_eax & 0xff)
  709.   {
  710.     case 0x00:
  711.     case 0x01:
  712.     case 0x06:
  713.     case 0x07:
  714.       intr(0x21, &r);
  715.       tss_ptr->tss_edx = r.r_dx;
  716.       tss_ptr->tss_eax = r.r_ax;
  717.       tss_ptr->tss_eflags = flmerge(r.r_flags, tss_ptr->tss_eflags);
  718.       return 0;
  719.     default:
  720.       return 1;
  721.   }
  722. }
  723.  
  724. tss2reg(struct REGPACK *r)
  725. {
  726.   r->r_ax = tss_ptr->tss_eax;
  727.   r->r_bx = tss_ptr->tss_ebx;
  728.   r->r_cx = tss_ptr->tss_ecx;
  729.   r->r_dx = tss_ptr->tss_edx;
  730.   r->r_si = tss_ptr->tss_esi;
  731.   r->r_di = tss_ptr->tss_edi;
  732.   r->r_flags = tss_ptr->tss_eflags;
  733.   r->r_ds = r->r_es = _DS;
  734. }
  735.  
  736. reg2tss(struct REGPACK *r)
  737. {
  738.   tss_ptr->tss_eax = r->r_ax;
  739.   tss_ptr->tss_ebx = r->r_bx;
  740.   tss_ptr->tss_ecx = r->r_cx;
  741.   tss_ptr->tss_edx = r->r_dx;
  742.   tss_ptr->tss_esi = r->r_si;
  743.   tss_ptr->tss_edi = r->r_di;
  744.   tss_ptr->tss_eflags = flmerge(r->r_flags, tss_ptr->tss_eflags);
  745. }
  746.